﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WebCommit.Common.Entitys;

namespace WebCommit.Crawler
{
	public abstract class Worker
	{
		private Thread BackWorker;
		protected List<WebResourceEntity> WebList;
		//protected HashSet<string> UrlHistory;
		private List<WebResourceEntity> ResolveList = new List<WebResourceEntity>();
		protected object WebListLockObj ;
		public Worker(List<WebResourceEntity> webList, object lockObj)
		{
			//BackWorker.WorkerSupportsCancellation = true;
			//BackWorker.DoWork += new DoWorkEventHandler(Worker_DoWork);
			//BackWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
			ThreadStart ts = new ThreadStart(Work);
			BackWorker = new Thread(ts);
			WebList = webList;
			//UrlHistory = urlHistory;
			WebListLockObj = lockObj;
		}

		public delegate void OnStarted(object sender, WorkerEventArgs e);
		public delegate void OnProgressChanged(object sender, WorkerEventArgs e);
		//public delegate void OnPaused(object sender, CrawlWorkerEventArgs e);
		public delegate void OnStoped(object sender, WorkerEventArgs e);

		public event OnStarted Started;
		public event OnProgressChanged ProgressChanged;
		//public event OnPaused Paused;
		public event OnStoped Stoped;

		public WorkerStatus CurrentStatus = WorkerStatus.Stoped;

		void WorkerCompleted(List<WebResourceEntity> list)
		{
			if (ProgressChanged != null)
				ProgressChanged.DynamicInvoke(this, new WorkerEventArgs() { UrlList = list });

			if (CurrentStatus != WorkerStatus.Stoped)
			{
				Thread.Sleep(10);
				Work();
			}
		}


		void Work()
		{
			List<WebResourceEntity> webList = PreWork(WebList);
			if (CurrentStatus != WorkerStatus.Working)
			{
				this.CurrentStatus = WorkerStatus.Working;
				if (Started != null)
				{
					Started.DynamicInvoke(this, new WorkerEventArgs() { UrlList = webList });
				}
			}
			List<WebResourceEntity> list = DoWork(webList);
			//e.Result = list;
		//	WebList.AddRange(list);
			ResolveList.AddRange(webList);
			WorkerCompleted(list);
		}


		/// <summary>
		/// 预处理，返回需要处理的WebResource
		/// </summary>
		/// <param name="webList"></param>
		/// <returns></returns>
		public abstract List<WebResourceEntity> PreWork(List<WebResourceEntity> webList);

		/// <summary>
		/// 处理，传入预处理返回的List
		/// </summary>
		/// <param name="webList"></param>
		/// <returns></returns>
		public abstract List<WebResourceEntity> DoWork(List<WebResourceEntity> webList);
		

		public void Start()
		{
			//this.CurrentStatus = WorkerStatus.Working;
			BackWorker.Start();
		}

		//public void Pause()
		//{
		//    this.CurrentStatus = CrawlWorkerStatus.Paused;
		//    BackWorker.CancelAsync();
		//}

		public void Stop()
		{
			try
			{
				BackWorker.Abort();
			}
			catch
			{ }
			this.CurrentStatus = WorkerStatus.Stoped;
			if (Stoped != null)
			{
				Stoped.DynamicInvoke(this, new WorkerEventArgs() { UrlList = ResolveList });
			}

		}
	}
}
